
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define STATE_MENU		0
#define STATE_GAMEPLAY		1
#define STATE_PAUSE		2

//The headers
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_gfxPrimitives.h>
#include <SDL/SDL_mouse.h>
#include <string>
#include "player.h"
#include "Monster.h"
#include "Timer.h"

//The attributes of the screen
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
const int SCREEN_BPP = 32;
const int FRAMES_PER_SECOND = 60;


SDL_Surface *load_image( std::string filename )
{
	//The image that's loaded
	SDL_Surface* loadedImage = NULL;
	//The optimized image that will be used
	SDL_Surface* optimizedImage = NULL;
	//Load the image using SDL_image
	loadedImage = IMG_Load( filename.c_str() );
	//If the image loaded
	if( loadedImage != NULL )
	{
		//Create an optimized image
		optimizedImage = SDL_DisplayFormatAlpha( loadedImage );
		//Free the old image
		SDL_FreeSurface( loadedImage );
	}
	//Return the optimized image
	return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
	//Make a temporary rectangle to hold the offsets
	SDL_Rect offset;
	
	//Give the offsets to the rectangle
	offset.x = x;
	offset.y = y;
	
	//Blit the surface
	SDL_BlitSurface( source, NULL, destination, &offset );
}

void apply_surface( int x, int y, int width, int height, SDL_Surface* source, SDL_Surface* destination )
{
	//Make a temporary rectangle to hold the offsets
	SDL_Rect offset;
	
	//Give the offsets to the rectangle
	offset.x = x;
	offset.y = y;
	offset.w = width;
	offset.h = height;
	
	//Blit the surface
	SDL_BlitSurface( source, NULL, destination, &offset );
}

//The surfaces that will be used
//SDL_Surface *message = NULL;
SDL_Surface *background = NULL;
SDL_Surface *paused = NULL;
SDL_Surface *menu = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *monster = NULL;
SDL_Surface *guy = NULL;
SDL_Event event;

bool quit = false;
Player Guy;
Monster evil;
int state;

int frame;
Timer fps;

void render()
{
	switch (state)
	{
		case STATE_MENU:
			apply_surface(        0,        0,		menu,screen);
			break;
		case STATE_GAMEPLAY:
			apply_surface(        0,        0,	  background,screen);
			apply_surface( Guy.x-16, Guy.y-16,      	 guy,screen);
			apply_surface(evil.x-16,evil.y-16,	     monster,screen);
			int x, y;
			if (SDL_GetMouseState(&x,&y)&SDL_BUTTON(1))
			{
				aalineRGBA(screen,Guy.x,Guy.y,x,y,rand()%255,rand()%255,rand()%255,255);
				if (evil.x-16 < x && evil.x+16 > x &&
					evil.y-16 < y && evil.y+16 > y)
				{
					evil.shot();
				}
				Guy.shooting = true;
			}
			else
				Guy.shooting = false;
			break;
		case STATE_PAUSE:
			apply_surface(        0,        0,    	      paused,screen);
			break;
	}
}

int main( int argc, char* args[] )
{
	//Initialize all SDL subsystems
	if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
	{
		printf("SDL_INIT failed");
		return 1;
	}
	state = STATE_MENU;
	//Set up the screen
	screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
	
	//If there was an error in setting up the screen
	if( screen == NULL )
	{
		printf("Screen was null");
		return 1;
	}
	
	//Set the window caption
	SDL_WM_SetCaption( "Monster Chase", NULL );
	
	//Load the images
	guy = load_image("img/guy.png");
	background = load_image("img/background.png");
	paused = load_image("img/paused.png");
	menu = load_image("img/menu.png");
	monster = load_image("img/monster.png");

	if (!guy || !background || !paused || !menu || !monster)
	{
		printf("Picture loading failed!!!");
		return 1;
	}

	Guy.x = SCREEN_WIDTH/2;
	Guy.y = SCREEN_HEIGHT/2;
	evil.difficulty = 0.1f;
	printf("\nInit finished\n");

	while (!quit)
	{
		fps.start();
		//If there's an event to handle
		if( SDL_PollEvent( &event ) )
		{
			//If the user has Xed out the window
			if( event.type == SDL_QUIT )
			{
				//Quit the program
				quit = true;
			}
		}
		Uint8 *keystates = SDL_GetKeyState( NULL );
		switch (state)
		{
			case STATE_MENU:
				if (keystates[SDLK_SPACE])
					state = STATE_GAMEPLAY;
				if (keystates[SDLK_F4])
					quit = true;
				break;
			case STATE_PAUSE:
				if (keystates[SDLK_SPACE])
					state = STATE_GAMEPLAY;
				if (keystates[SDLK_F4])
					quit = true;
				break;
			case STATE_GAMEPLAY:
				Guy.move(keystates);
				Guy.update();
				evil.move(Guy.x,Guy.y);
				evil.update();
				// Player inside
				if (Guy.x < evil.x+16 && Guy.x > evil.x-16 &&
				      Guy.y < evil.y+16 && Guy.y > evil.y-16)
				{
				    Guy.x = SCREEN_WIDTH/2;
				    Guy.y = SCREEN_HEIGHT/2;
				    evil.difficulty -= 0.05f;
				}
				if (keystates[SDLK_ESCAPE])
					state = STATE_PAUSE;
				break;
		}	
		render();
		
		//Update the screen
		if( SDL_Flip( screen ) == -1 )
		{
			return 1;
		}
		++frame;
		if (fps.get_ticks() < 1000 / FRAMES_PER_SECOND)
		{
			// Wait
			int wait = ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks();
			SDL_Delay(wait);
			if (frame % 10 == 0) printf ("Wait: %d\n",wait);
		}
	}
	//Free the surfaces
	SDL_FreeSurface(         guy);
	SDL_FreeSurface(  background);
	SDL_FreeSurface(      paused);
	SDL_FreeSurface(        menu);
	SDL_FreeSurface(     monster);
	
	//Quit SDL
	SDL_Quit();
	
	return 0;
}
